/**
 * proxy 函数
 *
 * @Author bian
 * @CreateDate 2016.10.23
 */
var Url = require("url").Url;
var format = require("url").format;

// init request
var superagentPromisePlugin = require("superagent-promise-plugin");
require("es6-promise").polyfill();
var request = superagentPromisePlugin.patch(require("superagent"));
var charset = require("superagent-charset");
charset(request);

var debug = require("debug")("nodeApiProxy");

var _extend = function(newObj,obj){
    Object.keys(obj).forEach((k) => {
        newObj[k] = obj[k];
    });
    return newObj;
};

var _isEmptyObj = function(obj){
    var i;
    for(i in obj){
        return false;
    }
    return true;
};

var isDebug = process.env.DEBUG !== null && typeof process.env.DEBUG !== "undefined";

/**
 * req2res转换器
 * @param ctx context上下文
 * @param url
 */
var reqToRes = function * (ctx,url){
    var req
        ,res;

    if(ctx.request.method == "GET"){

        req = req ? req.get(url) : request.get(url);

    }else if(ctx.request.method == "POST"){
        var body = ctx.request.body;

        req = req ? req.post(url) : request.post(url);
        req = _isEmptyObj(body) ? req : req.send(body);

    }else{
        throw new Error("不支持该方法");
    }

    var header = _extend(ctx.headers,ctx.header);
    Object.keys(header).forEach((k) => {
        req = req ? req.set(k,header[k]) : request.set(k,header[k]);
    })

    try{
        res = yield req;
    }catch(err){
        res = {
            text : err
        }
    }

    return res;
};

exports.reqToRes = reqToRes;

/**
 * 全局代理函数
 * @param prefix  带有这个prefix的路由都会被代理
 * @param options 路由的对象 protocol,host,port
 */
var apiProxy = function(prefix,options){
    prefix = `\\/${prefix}`;

    return function * (next){
        var url = new Url();
        url.protocol = options.protocol || "http";
        url.hostname = options.host || "localhost";
        url.port = options.port || 80;

        var ctx = this;

        var regx = new RegExp(prefix,"gi");
        url.pathname = ctx.req.url.replace(regx,"");
        url = decodeURIComponent(format(url));

        isDebug && console.info("nodeApiProxy request",ctx.request.method + ":",url);

        if(! regx.test(ctx.req.url)){       // 如果没有命中，返回
            yield next;
            return;
        }

        var res = yield reqToRes(ctx,url);
        isDebug && console.info("nodeApiProxy response",res.text);

        // todo: set header of res here
        ctx.body = res.text
        // ctx.response = res
    }
};

exports.apiProxy = apiProxy;

/**
 * 预处理代理函数
 * @Usage
 * router.get("",transProxy,function*(){
 *      console.log(ctx.proxyCache);
 * })
 */
var transProxy = function * (next){
    var ctx = this;
    ctx.proxyCache = yield reqToRes(ctx);
    isDebug && debug("nodeApiProxy cache",ctx.proxyCache);
    yield next;
};

exports.transProxy = transProxy;
